<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    html,
    body {
      width: 100%;
      height: 100vh;
      background-color: antiquewhite;
      overflow: hidden;
    }

    .wrap {
      width: 800px;
      height: 800px;
      border: 1px solid #000;
      position: relative;
    }

    .box {
      width: 100px;
      height: 100px;
      background-color: red;
      touch-action: none;
      user-select: none;
      display: grid;
      place-items: center;
      position: absolute;

    }
  </style>
</head>

<body>
  <div class="wrap">
    <div class=" box">
      按住移动
    </div>
  </div>



  <script>

    // 支持 PC端  移动端 触摸板
    let startX = 0
    let startY = 0
    const box = document.querySelector('.box')
    box.addEventListener('pointerdown', function (e) {
      box.setPointerCapture(e.pointerId);
      box.style.cursor = 'move'
      startX = e.pageX - startX
      startY = e.pageY - startY
      const handleMove = (e) => {
        const diffX = e.pageX - startX
        const diffY = e.pageY - startY
        const { top, left, width, height } = box.getBoundingClientRect()
        // 计算新的位置
        let newLeft = diffX;
        let newTop = diffY;
        // 限制在视口内  
        // newLeft 小于  box.parentElement.getBoundingClientRect().left 可限制在父元素内移动
        if (newLeft < 0) {
          newLeft = 0;
        }
        // window.innerWidth 替换成  box.parentElement.offsetWidth 可限制在父级元素内移动
        if (newLeft > window.innerWidth - box.offsetWidth) {
          newLeft = window.innerWidth - box.offsetWidth;
        }
        // newLeft 小于  box.parentElement.getBoundingClientRect().top 可限制在父元素内移动
        if (newTop < 0) {
          newTop = 0;
        }
        // window.innerHeight 替换成 box.parentElement.offsetHeight 可限制在父级元素内移动
        if (newTop > window.innerHeight - box.offsetHeight) {
          newTop = window.innerHeight - box.offsetHeight;
        }
        box.style.transform = `translate(${newLeft}px, ${newTop}px)`;
      }
      const handleUp = (e) => {
        startX = e.pageX - e.offsetX
        startY = e.pageY - e.offsetY
        box.style.cursor = 'auto'
        box.removeEventListener('pointermove', handleMove);
        box.removeEventListener('pointerup', handleUp);
      }

      box.addEventListener('pointermove', handleMove);
      box.addEventListener('pointerup', handleUp,);
    })
  </script>
</body>

</html>